From: Keir Fraser Date: Fri, 26 Sep 2008 13:05:41 +0000 (+0100) Subject: x86 and ia64: move cpufreq notify code to commone place X-Git-Tag: archive/raspbian/4.8.0-1+rpi1~1^2~14101^2~15 X-Git-Url: https://dgit.raspbian.org/%22http:/www.example.com/cgi/%22https:/%22bookmarks://%22Dat/%22http:/www.example.com/cgi/%22https:/%22bookmarks:/%22Dat?a=commitdiff_plain;h=452119c09420458bc60b4824658ca6be15bc4a10;p=xen.git x86 and ia64: move cpufreq notify code to commone place This patch move the cpufreq notify code from x86 specfic place to common place, since it can be used by both x86 and ia64 cpufreq driver. Signed-off-by: Liu Jinsong Signed-off-by: Yu Ke --- diff --git a/xen/arch/x86/acpi/cpufreq/cpufreq.c b/xen/arch/x86/acpi/cpufreq/cpufreq.c index 0798a4c9b1..45a0a53094 100644 --- a/xen/arch/x86/acpi/cpufreq/cpufreq.c +++ b/xen/arch/x86/acpi/cpufreq/cpufreq.c @@ -584,3 +584,21 @@ static int __init cpufreq_driver_init(void) return ret; } __initcall(cpufreq_driver_init); + +int cpufreq_cpu_init(unsigned int cpuid) +{ + static int cpu_count=0; + int ret; + + cpu_count++; + + /* Currently we only handle Intel and AMD processor */ + if ( boot_cpu_data.x86_vendor == X86_VENDOR_INTEL ) + ret = cpufreq_add_cpu(cpuid); + else if ( (boot_cpu_data.x86_vendor == X86_VENDOR_AMD) && + (cpu_count == num_online_cpus()) ) + ret = powernow_cpufreq_init(); + else + ret = -EFAULT; + return ret; +} diff --git a/xen/arch/x86/platform_hypercall.c b/xen/arch/x86/platform_hypercall.c index 72c6648deb..99060a0d56 100644 --- a/xen/arch/x86/platform_hypercall.c +++ b/xen/arch/x86/platform_hypercall.c @@ -45,6 +45,7 @@ extern spinlock_t xenpf_lock; static DEFINE_PER_CPU(uint64_t, freq); +extern int set_px_pminfo(uint32_t cpu, struct xen_processor_performance *perf); extern long set_cx_pminfo(uint32_t cpu, struct xen_processor_power *power); static long cpu_frequency_change_helper(void *data) @@ -52,6 +53,15 @@ static long cpu_frequency_change_helper(void *data) return cpu_frequency_change(this_cpu(freq)); } +int xenpf_copy_px_states(struct processor_performance *pxpt, + struct xen_processor_performance *dom0_px_info) +{ + if (!pxpt || !dom0_px_info) + return -EINVAL; + return copy_from_compat(pxpt->states, dom0_px_info->states, + dom0_px_info->state_count); +} + ret_t do_platform_op(XEN_GUEST_HANDLE(xen_platform_op_t) u_xenpf_op) { ret_t ret = 0; @@ -363,99 +373,9 @@ ret_t do_platform_op(XEN_GUEST_HANDLE(xen_platform_op_t) u_xenpf_op) { case XEN_PM_PX: { - static int cpu_count = 0; - struct xenpf_set_processor_pminfo *xenpmpt = &op->u.set_pminfo; - struct xen_processor_performance *xenpxpt = &op->u.set_pminfo.perf; - int cpuid = get_cpu_id(xenpmpt->id); - struct processor_pminfo *pmpt; - struct processor_performance *pxpt; - - if ( !(xen_processor_pmbits & XEN_PROCESSOR_PM_PX) ) - { - ret = -ENOSYS; - break; - } - if ( cpuid < 0 ) - { - ret = -EINVAL; - break; - } - pmpt = processor_pminfo[cpuid]; - if ( !pmpt ) - { - pmpt = xmalloc(struct processor_pminfo); - if ( !pmpt ) - { - ret = -ENOMEM; - break; - } - memset(pmpt, 0, sizeof(*pmpt)); - processor_pminfo[cpuid] = pmpt; - } - pxpt = &pmpt->perf; - pmpt->acpi_id = xenpmpt->id; - pmpt->id = cpuid; - - if ( xenpxpt->flags & XEN_PX_PCT ) - { - memcpy ((void *)&pxpt->control_register, - (void *)&xenpxpt->control_register, - sizeof(struct xen_pct_register)); - memcpy ((void *)&pxpt->status_register, - (void *)&xenpxpt->status_register, - sizeof(struct xen_pct_register)); - } - if ( xenpxpt->flags & XEN_PX_PSS ) - { - if ( !(pxpt->states = xmalloc_array(struct xen_processor_px, - xenpxpt->state_count)) ) - { - ret = -ENOMEM; - break; - } - if ( copy_from_compat(pxpt->states, xenpxpt->states, - xenpxpt->state_count) ) - { - xfree(pxpt->states); - ret = -EFAULT; - break; - } - pxpt->state_count = xenpxpt->state_count; - } - if ( xenpxpt->flags & XEN_PX_PSD ) - { - pxpt->shared_type = xenpxpt->shared_type; - memcpy ((void *)&pxpt->domain_info, - (void *)&xenpxpt->domain_info, - sizeof(struct xen_psd_package)); - } - if ( xenpxpt->flags & XEN_PX_PPC ) - { - pxpt->platform_limit = xenpxpt->platform_limit; - - if ( pxpt->init == XEN_PX_INIT ) - { - ret = cpufreq_limit_change(cpuid); - break; - } - } - - if ( xenpxpt->flags == ( XEN_PX_PCT | XEN_PX_PSS | - XEN_PX_PSD | XEN_PX_PPC ) ) - { - pxpt->init = XEN_PX_INIT; - cpu_count++; - - /* Currently we only handle Intel and AMD processor */ - if ( boot_cpu_data.x86_vendor == X86_VENDOR_INTEL ) - ret = cpufreq_add_cpu(cpuid); - else if ( (boot_cpu_data.x86_vendor == X86_VENDOR_AMD) && - (cpu_count == num_online_cpus()) ) - ret = powernow_cpufreq_init(); - else - break; - } + ret = set_px_pminfo(op->u.set_pminfo.id, + &op->u.set_pminfo.perf); break; } diff --git a/xen/arch/x86/x86_64/platform_hypercall.c b/xen/arch/x86/x86_64/platform_hypercall.c index 037ab4f4af..02364c4535 100644 --- a/xen/arch/x86/x86_64/platform_hypercall.c +++ b/xen/arch/x86/x86_64/platform_hypercall.c @@ -11,6 +11,8 @@ DEFINE_XEN_GUEST_HANDLE(compat_platform_op_t); #define xen_platform_op_t compat_platform_op_t #define do_platform_op(x) compat_platform_op(_##x) +#define xenpf_copy_px_states compat_xenpf_copy_px_states + #define xen_processor_px compat_processor_px #define xen_processor_px_t compat_processor_px_t #define xen_processor_performance compat_processor_performance diff --git a/xen/drivers/cpufreq/cpufreq.c b/xen/drivers/cpufreq/cpufreq.c index d4dae5bfd3..156adfca50 100644 --- a/xen/drivers/cpufreq/cpufreq.c +++ b/xen/drivers/cpufreq/cpufreq.c @@ -34,13 +34,12 @@ #include #include #include +#include #include -#include #include #include #include #include -#include #include #include @@ -82,7 +81,7 @@ int cpufreq_add_cpu(unsigned int cpu) if (!processor_pminfo[cpu] || !(perf->init & XEN_PX_INIT)) return 0; - if (cpu_is_offline(cpu) || cpufreq_cpu_policy[cpu]) + if (!cpu_online(cpu) || cpufreq_cpu_policy[cpu]) return -EINVAL; ret = cpufreq_statistic_init(cpu); @@ -158,7 +157,7 @@ int cpufreq_del_cpu(unsigned int cpu) if (!processor_pminfo[cpu] || !(perf->init & XEN_PX_INIT)) return 0; - if (cpu_is_offline(cpu) || !cpufreq_cpu_policy[cpu]) + if (!cpu_online(cpu) || !cpufreq_cpu_policy[cpu]) return -EINVAL; dom = perf->domain_info.domain; @@ -186,3 +185,123 @@ int cpufreq_del_cpu(unsigned int cpu) return 0; } +static void print_PSS(struct xen_processor_px *ptr, int count) +{ + int i; + printk(KERN_INFO "\t_PSS:\n"); + for (i=0; inum_entries, ptr->revision, ptr->domain, ptr->coord_type, + ptr->num_processors); +} + +int set_px_pminfo(uint32_t acpi_id, struct xen_processor_performance *dom0_px_info) +{ + int cpu_count = 0, ret=0, cpuid; + struct processor_pminfo *pmpt; + struct processor_performance *pxpt; + + if ( !(xen_processor_pmbits & XEN_PROCESSOR_PM_PX) ) + { + ret = -ENOSYS; + goto out; + } + + cpuid = get_cpu_id(acpi_id); + if ( cpuid < 0 ) + { + ret = -EINVAL; + goto out; + } + printk(KERN_INFO "Set CPU acpi_id(%d) cpuid(%d) Px State info:\n", + acpi_id, cpuid); + + pmpt = processor_pminfo[cpuid]; + if ( !pmpt ) + { + pmpt = xmalloc(struct processor_pminfo); + if ( !pmpt ) + { + ret = -ENOMEM; + goto out; + } + memset(pmpt, 0, sizeof(*pmpt)); + processor_pminfo[cpuid] = pmpt; + } + pxpt = &pmpt->perf; + pmpt->acpi_id = acpi_id; + pmpt->id = cpuid; + + if ( dom0_px_info->flags & XEN_PX_PCT ) + { + memcpy ((void *)&pxpt->control_register, + (void *)&dom0_px_info->control_register, + sizeof(struct xen_pct_register)); + memcpy ((void *)&pxpt->status_register, + (void *)&dom0_px_info->status_register, + sizeof(struct xen_pct_register)); + } + if ( dom0_px_info->flags & XEN_PX_PSS ) + { + if ( !(pxpt->states = xmalloc_array(struct xen_processor_px, + dom0_px_info->state_count)) ) + { + ret = -ENOMEM; + goto out; + } + if ( xenpf_copy_px_states(pxpt, dom0_px_info) ) + { + xfree(pxpt->states); + ret = -EFAULT; + goto out; + } + pxpt->state_count = dom0_px_info->state_count; + print_PSS(pxpt->states,pxpt->state_count); + } + if ( dom0_px_info->flags & XEN_PX_PSD ) + { + pxpt->shared_type = dom0_px_info->shared_type; + memcpy ((void *)&pxpt->domain_info, + (void *)&dom0_px_info->domain_info, + sizeof(struct xen_psd_package)); + print_PSD(&pxpt->domain_info); + } + if ( dom0_px_info->flags & XEN_PX_PPC ) + { + pxpt->platform_limit = dom0_px_info->platform_limit; + + if ( pxpt->init == XEN_PX_INIT ) + { + + ret = cpufreq_limit_change(cpuid); + goto out; + } + } + + if ( dom0_px_info->flags == ( XEN_PX_PCT | XEN_PX_PSS | + XEN_PX_PSD | XEN_PX_PPC ) ) + { + pxpt->init = XEN_PX_INIT; + cpu_count++; + + ret = cpufreq_cpu_init(cpuid); + goto out; + } + +out: + return ret; +} + diff --git a/xen/include/acpi/cpufreq/processor_perf.h b/xen/include/acpi/cpufreq/processor_perf.h index b9c934da51..7821aeffb1 100644 --- a/xen/include/acpi/cpufreq/processor_perf.h +++ b/xen/include/acpi/cpufreq/processor_perf.h @@ -60,4 +60,8 @@ struct pm_px { extern struct pm_px *cpufreq_statistic_data[NR_CPUS]; +int xenpf_copy_px_states(struct processor_performance *pxpt, + struct xen_processor_performance *dom0_px_info); + +int cpufreq_cpu_init(unsigned int cpuid); #endif /* __XEN_PROCESSOR_PM_H__ */